package wiBase.baseObject;

import java.awt.Color;
import java.awt.Graphics2D;
import java.util.ArrayList;
import wiBase.WiObject;
import wiBase.baseUtil.Form;
import wiBase.baseUtil.Position;
import wiBase.baseUtil.Size;
import wiBase.baseUtil.Velocity;

public class Node extends WiObject {

    public int id;
    public String title;
    public Color color;
    public Color titleColor;
    public Position position;
    public Size size = new Size(0, 0);
    public Form form = new Form(Form.MODE_DEFAULT);
    public boolean isVisible = true;
    public Velocity velocity;
    /**
     * energy of node
     */
    public double energy = 0D;
    /**
     * range of node could connectivity
     */
    public double range = 0D;
    public double x, y;
    private boolean isSleep = false;
    public ArrayList<Packet> queue;
    public ArrayList<Link> links;

    public Node() {
	this(-1);
    }

    public Node(int id) {
	this.id = id;
	position = new Position(this, -1, -1);
    }

    public void paint(Graphics2D graphics) {
	// draw title
	graphics.setColor(titleColor);

//		graphics.drawString(title, position.getX(), position.getY());
    }

    public boolean isSleep() {
	return isSleep;
    }

    public void setSleep(boolean isSleeping) {
	this.isSleep = isSleeping;
    }

    @Override
    public String toString() {
	return "Node [id=" + id + ", title=" + title + ", color=" + color
		+ ", titleColor=" + titleColor + ", position=" + position
		+ ", size=" + size + ", form=" + form + ", isVisible="
		+ isVisible + ", velocity=" + velocity + ", energy=" + energy
		+ ", range=" + range + ", queue=" + queue + ", links=" + links
		+ ", isChangeable()=" + isChangeable() + "]";
    }

    public double getX() {
	return x;
    }

    public double getY() {
	return y;
    }
    // seriable is a event
    /**
     * if the node is traced, this method would be called.
     */
    public void run(String type, WiObject... seriable) {

	Event event = (Event) seriable[0];
	switch (type) {
	    case "send":
	    case "forward":
	    case "receive":
		break;
	    case "drop":
		break;
	    case "move":
		try {
		    position.setX(Double.parseDouble(event.destX));
		    position.setY(Double.parseDouble(event.destY));
		    velocity.getPosSource().setX(Double.parseDouble(event.currX));
		    velocity.getPosSource().setY(Double.parseDouble(event.currY));
		    velocity.getPosDestination().setX(Double.parseDouble(event.destX));
		    velocity.getPosDestination().setY(Double.parseDouble(event.destY));
		    velocity.setSpeed(Double.parseDouble(event.speed));
		} catch (NumberFormatException e) {
		    e.printStackTrace();
		}

		break;
	    case "sleep":
		setSleep(true);
		break;
	    case "wake":
		setSleep(false);
		break;

	    default:
		break;
	}
	// call back
	if (getOutputListener() == null) {
	    return;
	}
	Node _node_ = this;
	int size = seriable.length;
	WiObject[] seri = new WiObject[size + 1];
	for (int i = 0; i < size; ++i) {
	    seri[i] = seriable[i];
	}
	seri[size] = _node_;
	getOutputListener().write(type, seri);
    }
    /**
     * inflate variable matching with attrName with value=attrValue.
     */
    public static Node parseValue(String[] attrName, String[] attrValue) {
	Node _node = new Node(-1);
	for (int i = 0; i < attrName.length; ++i) {
	    if (attrName[i].equals("id")) {
		_node.id = Integer.valueOf(attrValue[i]);
	    } else if (attrName[i].equals("range")) {
		_node.range = Double.valueOf(attrValue[i]);
	    } else if (attrName[i].equals("x")) {
		_node.position.setX(Double.valueOf(attrValue[i]));
	    } else if (attrName[i].equals("y")) {
		_node.position.setY(Double.valueOf(attrValue[i]));
	    } else if (attrName[i].equals("energy")) {
		_node.energy = Double.valueOf(attrValue[i]);
	    }
	}
	return _node;
    }
}
